    // Copyright (C) 2003  Davis E. King (davis@dlib.net)
    // License: Boost Software License   See LICENSE.txt for the full license.
    #ifndef DLIB_XML_PARSER_KERNEl_INTERFACES_
    #define DLIB_XML_PARSER_KERNEl_INTERFACES_

    #include <string>
    #include "../interfaces/enumerable.h"
    #include "../interfaces/map_pair.h"
    #include "../error.h"

    namespace dlib
    {

    // ----------------------------------------------------------------------------------------

        class xml_attribute_list_error : public dlib::error
        {
            /*!
                WHAT THIS OBJECT REPRESENTS
                    This is an exception object thrown by attribute_list objects if you try to
                    access a non-existent attribute.
            !*/
        public:
            xml_attribute_list_error(const std::string& msg) : dlib::error(msg){}
        };

    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------

        class attribute_list : public enumerable<map_pair<std::string,std::string> >
        {

            /*!
                WHAT THIS OBJECT REPRESENTS
                    this object represents a list of the attributes found in
                    an XML element.  each attribute is associated with a value.
            !*/

        public:

            inline virtual ~attribute_list (
            ) =0;

            virtual bool is_in_list (
                const std::string& key
            ) const =0;
            /*!
                ensures
                    - returns true if there is an attribute named key in the list
                    - returns false
            !*/

            virtual const std::string& operator[] (
                const std::string& key
            ) const =0;
            /*!
                ensures
                    if (is_in_list(key) == true) then
                        - returns a const reference to the value associated with the attribute
                          named key.
                    - else
                        - throws xml_attribute_list_error
            !*/

        protected:

            // restricted functions
            attribute_list& operator=(attribute_list&) {return *this;}
        };

    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------

        class document_handler
        {
            /*!
                EXCEPTIONS
                    a document_handler is allowed to throw any exception

                WHAT THIS OBJECT REPRESENTS
                    this object is an interface for handling the basic events
                    generated by an XML parser
            !*/

        public:

            inline virtual ~document_handler (
            ) =0;

            virtual void start_document (
            )=0;
            /*!
                requires
                    - is called when the document parsing begins
            !*/

            virtual void end_document (
            )=0;
            /*!
                requires
                    - is called after the document parsing has ended.  note that this
                      is always called, even if an error occurs.
            !*/

            virtual void start_element (
                const unsigned long line_number,
                const std::string& name,
                const dlib::attribute_list& atts
            )=0;
            /*!
                requires
                    - is called when an opening element tag is encountered.
                    - line_number == the line number where the opening tag for this element
                      was encountered.
                    - name == the name of the element encountered
                    - atts == a list containing all the attributes in this element and their
                      associated values
            !*/

            virtual void end_element (
                const unsigned long line_number,
                const std::string& name
            )=0;
            /*!
                requires
                    - is called when a closing element tag is encountered. (note that this
                      includes tags such as <example_tag/>.  I.e. the previous tag would
                      trigger a start_element() callback as well as an end_element() callback)
                    - line_number == the line number where the closing tag for this
                      element was encountered and
                    - name == the name of the element encountered
            !*/

            virtual void characters (
                const std::string& data
            )=0;
            /*!
                requires
                    - is called just before we encounter a start_element, end_element, or
                      processing_instruction tag but only if there was data between the
                      last and next tag.
                      (i.e. data will never be "")
                    - data == all the normal non-markup data and CDATA between the next and
                      last tag in the document.
            !*/

            virtual void processing_instruction (
                const unsigned long line_number,
                const std::string& target,
                const std::string& data
            )=0;
            /*!
                requires
                    - is called when a processing instruction is encountered
                    - line_number == the line number where this processing instruction
                      was encountered
                    - target == the target value for this processing instruction
                    - data == the data value for this processing instruction
            !*/

        protected:

            // restricted functions
            document_handler& operator=(document_handler&) { return *this; }
        };

    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------

        class error_handler
        {
            /*!
                EXCEPTIONS
                    an error_handler is allowed to throw any exception

                WHAT THIS OBJECT REPRESENTS
                    this object is an interface for handling the error/warning
                    events generated by an XML parser
            !*/

        public:

            inline virtual ~error_handler (
            ) =0;

            virtual void error (
                const unsigned long line_number
            )=0;
            /*!
                requires
                    - is called when an error that does NOT require the parser to halt
                      is encountered. (i.e. somewhat minor errors in the input)
                    - line_number == the line number where this error was encountered

                the following events trigger an error:
                    an invalid processing instruction
            !*/

            virtual void fatal_error (
                const unsigned long line_number
            )=0;
            /*!
                requires
                    - is called when an error that requires the parser to abort its parsing
                      is encountered (i.e. fatal errors in the input)
                    - line_number == the line number where this fatal error was encountered

                the following events trigger a fatal_error:
                    Everything other than the events listed above for error.
                    Also note that encountering an entity reference other than the
                    predefined ones listed in xml_parser_kernel_abstract is a fatal_error.
                    Hitting EOF before the closing tag for the document is also a fatal_error.
            !*/

        protected:

            // restricted functions
            error_handler& operator=(error_handler&) { return *this;}
        };

    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------
    // ----------------------------------------------------------------------------------------

        document_handler::~document_handler (
        ){}
        attribute_list::~attribute_list (
        ){}
        error_handler::~error_handler (
        ){}

    }

    #endif // DLIB_XML_PARSER_KERNEl_INTERFACES_